package club.cearnach.api.service.impl;

import club.cearnach.api.dao.IAdminDao;
import club.cearnach.api.dao.IRoleDao;
import club.cearnach.api.exception.AdminException;
import club.cearnach.api.exception.RoleNotFoundException;
import club.cearnach.api.form.PageBean;
import club.cearnach.api.service.IAdminService;
import club.cearnach.entity.Admin;
import club.cearnach.entity.Role;
import club.cearnach.security.enumeration.RoleEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Optional;


/**
 * @author 阮胜
 * @date 2018/5/13 23:29
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class AdminServiceImpl implements IAdminService {
    private final IAdminDao adminDao;
    private final IRoleDao roleDao;
    public AdminServiceImpl(IAdminDao adminDao, IRoleDao roleDao) {
        this.adminDao = adminDao;
        this.roleDao = roleDao;
    }


    @Override
    public void delete(Integer id) throws AdminException {
        adminDao.findById(id).orElseThrow(() -> new AdminException(AdminException.ADMIN_CAN_NOT_FOUNT));
        adminDao.deleteById(id);
    }

    @Override
    public Admin save(Admin admin) {
        log.info("Save admin account = {} , password ={}", admin.getAccount(), admin.getPassword());
        return adminDao.save(admin);
    }

    @Override
    public Admin find(String account, String password) throws AdminException {
        return adminDao.findByAccountAndPassword(account, password).orElseThrow(() -> new AdminException(AdminException.ADMIN_CAN_NOT_FOUNT));
    }

    @Override
    public Optional<Admin> findByAccount(String account) {
        return adminDao.findByAccount(account);
    }
    @Override
    public Optional<Admin> findByAccountAndPrivilege(String account, RoleEnum roleEnum) throws RoleNotFoundException {
        Role role = roleDao.findByName(roleEnum.getRole()).orElseThrow(() -> new RoleNotFoundException());
        return adminDao.findByAccountAndRoleId(account, role.getId());
    }

    @Override
    public Admin find(Integer id) throws AdminException {
        return adminDao.findById(id).orElseThrow(() -> new AdminException(AdminException.ADMIN_CAN_NOT_FOUNT));
    }

    @Override
    public Admin find(Admin admin) throws AdminException {
        return adminDao.findByAccountAndPassword(admin.getAccount(), admin.getPassword()).orElseThrow(() -> new AdminException(AdminException.ADMIN_CAN_NOT_FOUNT));
    }

    @Override
    public Page<Admin> findAllOrderByCreateDate(PageBean pageBean) {
        return adminDao.findAll(PageRequest.of(pageBean.getPage(), pageBean.getSize(), Sort.by(Sort.Direction.DESC, "createDate")));
    }

    @Override
    public Page<Admin> findAll(Pageable pageable) {
        return adminDao.findAll(pageable);
    }

    @Override
    public Page<Admin> findByLastLoginDate() {
        return findAll(PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "lastLoginDate")));
    }

    @Override
    public List<Admin> findByIdIn(Integer... ids) {
        if (ids != null && ids.length > 0) {
            return adminDao.findByIdIn(ids);
        }
        return null;
    }

    @Override
    public void deleteIn(Integer... ids) {
        for (Integer id : ids) {
            try {
                delete(id);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    @Override
    public long count() {
        return adminDao.count();
    }

    @Override
    public boolean isExist(String account, Integer id) {
        return id == null || id == 0
                ? adminDao.findByAccount(account).isPresent()
                : adminDao.findByAccountAndIdNot(account, id).isPresent();
    }

    @Override
    public Optional<Admin> login(String account, String pwd) {
        Optional<Admin> adminOptional = adminDao.findByAccountAndPassword(account, pwd);
        adminOptional.ifPresent(admin -> {
            admin.setLastLoginDate(new Date());
            adminDao.save(admin);
        });
        return adminOptional;
    }


}
